/* hal_uart.c */
#include "hal_uart.h"

void UART_SetBaudrate(UART_Type * base, uint32_t src_clk_freq, uint32_t baudrate);

void UART_Init(UART_Type * base, UART_Init_Type * init)
{
    /* disable the periph before any settings. */
    base->CTRL0 = 0u; /* diable tx and rx. */
    
    /* setup format. */
    uint32_t ctrl1 = UART_CTRL1_FRAMESZ(init->DataBits) | UART_CTRL1_IDLESZ(init->IdleSize);

    if (init->StopBits == UART_StopBits_2b)
    {
        ctrl1 |= UART_CTRL1_STOPSZ_MASK;
    }
    
    if (init->Parity != UART_Parity_None)
    {
        ctrl1 |= UART_CTRL1_PAREN_MASK;
        if (init->Parity == UART_Parity_Odd)
        {
            ctrl1 |= UART_CTRL1_PARSEL_MASK;
        }
    }
    
    base->CTRL1 = ctrl1;
    
    /* setup baudrate. */
    UART_SetBaudrate(base, init->SrcClkFreq, init->Baudrate);
    
    /* setup the rx and tx fifo. */
    base->RXFIFO = UART_RXFIFO_EN_MASK | UART_RXFIFO_RESET_MASK;
    base->RXFIFO |= UART_RXFIFO_WATER(init->RxFifoWatermark);
    base->TXFIFO = UART_TXFIFO_EN_MASK | UART_TXFIFO_RESET_MASK;
    base->TXFIFO |= UART_TXFIFO_WATER(init->TxFifoWatermark);
    
    /* enable tx and rx. */
    base->CTRL0 |= UART_CTRL0_TXEN_MASK | UART_CTRL0_RXEN_MASK;
}

void UART_SetBaudrate(UART_Type * base, uint32_t src_clk_freq, uint32_t baudrate)
{
    /* osr = 16. */
    base->BAUD = (src_clk_freq / baudrate) >> 4u;
}

void UART_EnableRx(UART_Type * base, bool enable)
{
    if (enable)
    {
        base->CTRL0 |= UART_CTRL0_RXEN_MASK;
    }
    else
    {
        base->CTRL0 &= ~UART_CTRL0_RXEN_MASK;
    }
}

void UART_EnableTx(UART_Type * base, bool enable)
{
    if (enable)
    {
        base->CTRL0 |= UART_CTRL0_TXEN_MASK;
    }
    else
    {
        base->CTRL0 &= ~UART_CTRL0_TXEN_MASK;
    }
}



uint32_t UART_GetStatusFlags(UART_Type * base)
{
    return base->INTF;
}

void UART_ClearStatusFlags(UART_Type * base, uint32_t flags)
{
    base->INTF = flags;
}

void UART_EnableInterrupts(UART_Type * base, uint32_t flags)
{
    base->INTE |= flags;
}

void UART_DisableInterrupts(UART_Type * base, uint32_t flags)
{
    base->INTE &= ~flags;
}

uint32_t UART_GetEnabledInterrupts(UART_Type * base)
{
    return base->INTE;
}

void UART_PutTxFifoData(UART_Type * base, uint8_t dat)
{
    base->DATA = dat;
}

uint8_t UART_GetRxFifoData(UART_Type * base)
{
    return base->DATA;
}

void UART_EnableRxDma(UART_Type * base, bool enable)
{
    if (enable)
    {
        base->CTRL0 |= UART_CTRL0_RXDMAEN_MASK;
    }
    else
    {
        base->CTRL0 &= ~UART_CTRL0_RXDMAEN_MASK;
    }
}

void UART_EnableTxDma(UART_Type * base, bool enable)
{
    if (enable)
    {
        base->CTRL0 |= UART_CTRL0_TXDMAEN_MASK;
    }
    else
    {
        base->CTRL0 &= ~UART_CTRL0_TXDMAEN_MASK;
    }
}

#if 0
typedef struct
{
    uint8_t MatchValue;
} UART_MatchConf_Type;

void UART_EnableMatchMode(UART_Type * base, UART_MatchConf_Type * conf)
{

}
#endif

/* EOF. */

